fix(agent-core-v2): keep user-cancellation identity when aborting swarm tool runs - #3729
kimi-agent-bot wants to merge 1 commit into
Conversation
🦋 Changeset detectedLatest commit: 8224a9a The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: eeab7d6777
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
|
Codex Review: Didn't find any major issues. What shall we delve into next? Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
…rm tool runs Interrupting an AgentSwarm with Esc aborted turn tools without an abort reason, so the interruption lost its UserCancellationError identity and the swarm batch rejected instead of resolving per-subagent "aborted" results. The rejection then surfaced on a floating promise derived by promise.finally(cleanup) in SessionSwarmService, raising an unhandledRejection that killed the whole process with exit 1. - abort turn tools with the user-cancellation reason on the input.abort and abort-escalation paths in the agent machine - swallow the derived cleanup promise rejection in SessionSwarmService so a failing batch can no longer crash the process on its own - recognise user cancellations structurally across class copies so the human kernel (which cannot import _base) can flag its own reason
807f855 to
8224a9a
Compare
|
@codex review |
|
Codex Review: Something went wrong. Try again later by commenting “@codex review”. ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
|
@codex review |
|
Codex Review: Something went wrong. Try again later by commenting “@codex review”. ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
|
@codex review |
|
Codex Review: Something went wrong. Try again later by commenting “@codex review”. ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
|
@codex review |
|
Codex Review: Something went wrong. Try again later by commenting “@codex review”. ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
Problem
Interrupting an AgentSwarm (>=2 items running) with Esc in the TUI killed the whole process with exit 1 within ~1s, taking the main agent and all subagents down mid-turn with nothing in the log. Seen twice in production on 0.42.0.
Two faults chain together:
human/agent/machine.tsaborted turn tools viaentry.scope.abort()with no reason. The interruption therefore lost itsUserCancellationErroridentity and surfaced as a genericDOMException("This operation was aborted"). Infeatures/swarm/session/agentRunBatch.ts, thebatchAbortListener'sisUserCancellationcheck then failed, so the batch went down thefail()path and rejected instead of resolving per-subagent"aborted"results.features/swarm/session/sessionSwarmService.tsattached cleanup viapromise.finally(cleanup)and dropped the derived promise. When the batch rejects, that floating promise rejects unobserved ->unhandledRejection->run-shell.tsemergencyExit(1).Fault 2 stands on its own: any genuine
AgentRunBatchfailure (not just user interruption) crashed the process the same way.Fix
machine.ts: on theinput.abortand abort-escalation paths, turn-tool scopes are now aborted with the user-cancellation reason (abortTurnToolsUserCancelled/stopTurnToolsUserCancelled/abortSpawnedTools), so an interrupted swarm batch resolves per-subagent"aborted"results as designed. The plain turn-exit path (abortTurnTools/stopTurnTools) still aborts without a reason, keeping the "turn over" semantics distinct from user cancellation. The firstabort()latches the reason, so the later exit-path aborts cannot clobber it.sessionSwarmService.ts: the cleanup chain now ends in.catch(() => {}), so a rejecting batch can no longer crash the process through the floating derived promise. The returned promise still rejects to the caller unchanged._base(import-boundary rule: human is the pure kernel), so it gets its ownUserCancellationError(userCancelled = true, nameAbortError) inhuman/utils/abort.ts, and_base'sisUserCancellationnow also recognises cancellations structurally (userCancelled === true) across class copies.Tests
machine.test.ts: aborting a turn now passes aUserCancellationErrorreason to running turn tools.sessionSwarm.test.ts: a failing swarm batch no longer raises anunhandledRejectionwhilerun()still rejects to the caller.abort.test.ts:isUserCancellationrecognises a foreign class copy flagged withuserCancelled.All three fail before the fix and pass after. Full agent-core-v2 suite (6466 tests), typecheck, lint:imports, oxlint, build, and the no-comments check are green.